{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "#load \"..\\Extension\\LoadBaseTool.csx\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`string`是引用类型，注意看下面两个代码块的区别。\n",
    "\n",
    "区别在于，虽然`string`虽然是引用类型，但是`C#`的函数调用默认为值传递。\n",
    "\n",
    "**对引用内成员的定义，不会影响引用本身。但是如果是值传递时，对引用的复制进行修改，相当于将两个引用指向不同的对象。**\n",
    "\n",
    "这里的`_message`可以理解为是`@string`的一个新的引用（浅复制），但是在`Function`函数中，该引用指向了一个新的对象`\"Hello World\"`，和原来的引用`@string`断开了联系，此时`_message`和`@string`指向的已经不是同一个对象了。\n",
    "\n",
    "而使用`ref`关键字时，`_message`就是`@string`本身，而没有任何复制。因此如果`_message`指向了新对象，`@string`也会指向新对象`\"Hello World\"`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "empty\r\n"
     ]
    }
   ],
   "source": [
    "public void Function(string _message) => _message = \"Hello World\";\n",
    "\n",
    "string @string = \"empty\";\n",
    "Function(@string);\n",
    "@string.Dump();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World\r\n"
     ]
    }
   ],
   "source": [
    "public void Function(ref string _message) => _message = \"Hello World\";\n",
    "\n",
    "string @string = \"empty\";\n",
    "Function(ref @string);\n",
    "@string.Dump();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Environment.NewLine\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`Environment.NewLine`可以去除字符串开头的`\\n`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "字符串:\n",
      "12345\n",
      "字符串:12345\n"
     ]
    }
   ],
   "source": [
    "string _str1 = \"\\n12345\";\n",
    "string _str11 = _str1.TrimStart(Environment.NewLine.ToCharArray());\n",
    "Console.WriteLine($\"字符串:{_str1}\");\n",
    "Console.WriteLine($\"字符串:{_str11}\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`Environment.NewLine`可以去除字符串开头的`\\r`\n",
    "\n",
    "> 这里我不确定，因为`\\r`好像原来就没显示\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "12345\n",
      "字符串:12345\n"
     ]
    }
   ],
   "source": [
    "string _str2 = \"\\r12345\";\n",
    "string _str22 = _str2.TrimStart(Environment.NewLine.ToCharArray());\n",
    "Console.WriteLine($\"字符串:{_str2}\");\n",
    "Console.WriteLine($\"字符串:{_str22}\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`Environment.NewLine`可以去除字符串开头的`\\r\\n`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "字符串:\n",
      "12345\n",
      "字符串:12345\n"
     ]
    }
   ],
   "source": [
    "string _str3 = \"\\r\\n12345\";\n",
    "string _str33 = _str3.TrimStart(Environment.NewLine.ToCharArray());\n",
    "Console.WriteLine($\"字符串:{_str3}\");\n",
    "Console.WriteLine($\"字符串:{_str33}\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字符串中间的`\\r\\n`不行\n",
    "\n",
    "- Trim(Char) 从当前字符串中删除字符的所有前导和尾随实例。\n",
    "- Trim() 从当前字符串中删除所有前导和尾随空格字符。\n",
    "- Trim(Char[]) 从当前字符串中删除数组中指定的一组字符的所有前导和尾随匹配项。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "字符串:123\n",
      "45\n",
      "字符串:123\n",
      "45\n"
     ]
    }
   ],
   "source": [
    "string _str4 = \"123\\r\\n45\";\n",
    "string _str44 = _str4.Trim(Environment.NewLine.ToCharArray());\n",
    "Console.WriteLine($\"字符串:{_str4}\");\n",
    "Console.WriteLine($\"字符串:{_str44}\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 字符串分隔\n",
    "\n",
    "加入`StringSplitOptions.RemoveEmptyEntries`选项可以避免多个空格的问题\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "00, , 11, , 22, 33\n",
      "00, 11, 22, 33\n"
     ]
    }
   ],
   "source": [
    "string[] _string_1 = \"00  11  22 33\".Split(' ');\n",
    "string[] _string_2 = \"00  11  22 33\".Split(' ', StringSplitOptions.RemoveEmptyEntries);\n",
    "_string_1.Dump();\n",
    "_string_2.Dump();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## IsNullOrEmpty 的问题\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`string.IsNullOrWhiteSpace()` 方法在以下情况下会返回 `true`：\n",
    "\n",
    "1. **字符串为 `null`**：如果传入的字符串引用是 `null`，则返回 `true`。\n",
    "2. **字符串为空**：如果字符串是空字符串 `\"\"`，即没有任何字符，返回 `true`。\n",
    "3. **字符串只包含空白字符**：如果字符串只包含一个或多个空白字符，例如空格、制表符 (`\\t`)、换行符 (`\\n`)、回车符 (`\\r`)、垂直制表符 (`\\v`) 或者任何其他 Unicode 空白字符，返回 `true`。\n",
    "\n",
    "以下是一些示例，展示了 `string.IsNullOrWhiteSpace()` 方法会返回 `true` 的情况：\n",
    "\n",
    "```csharp\n",
    "string str1 = null;           // true, 因为 str1 是 null\n",
    "string str2 = \"\";            // true, 因为 str2 是空字符串\n",
    "string str3 = \" \";           // true, 因为 str3 只包含一个空格\n",
    "string str4 = \"\\t\\n\\r\\v\";     // true, 因为 str4 只包含制表符、换行符、回车符和垂直制表符\n",
    "string str5 = \"   \";         // true, 因为 str5 只包含空格\n",
    "string str6 = \"　\";          // true, 因为 str6 包含全角空格（Unicode 空白字符）\n",
    "```\n",
    "\n",
    "相反，如果字符串包含至少一个非空白字符，即使它包含其他空白字符，`string.IsNullOrWhiteSpace()` 也会返回 `false`：\n",
    "\n",
    "```csharp\n",
    "string str7 = \"a\";          // false, 因为 str7 包含一个非空白字符 'a'\n",
    "string str8 = \" a \";        // false, 因为 str8 包含一个非空白字符 'a'，尽管它也有空格\n",
    "```\n",
    "\n",
    "这个方法通常用于验证输入字符串，确保它们既不是 `null` 也不是无效的空白字符串，从而避免在处理字符串时出现错误。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "string _str1 = \"\";\n",
    "\n",
    "string.IsNullOrEmpty(_str1).Dump();\n",
    "string.IsNullOrWhiteSpace(_str1).Dump();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "string _str1 = \"\\0\";\n",
    "\n",
    "string.IsNullOrEmpty(_str1).Dump();\n",
    "string.IsNullOrWhiteSpace(_str1).Dump();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "string _str1 = \"\\r\";\n",
    "\n",
    "string.IsNullOrEmpty(_str1).Dump();\n",
    "string.IsNullOrWhiteSpace(_str1).Dump();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "string _str1 = \"\\n\";\n",
    "\n",
    "string.IsNullOrEmpty(_str1).Dump();\n",
    "string.IsNullOrWhiteSpace(_str1).Dump();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "string _str1 = \"\\r\\n\";\n",
    "\n",
    "string.IsNullOrEmpty(_str1).Dump();\n",
    "string.IsNullOrWhiteSpace(_str1).Dump();"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (C#)",
   "language": "C#",
   "name": ".net-csharp"
  },
  "language_info": {
   "name": "python"
  },
  "polyglot_notebook": {
   "kernelInfo": {
    "defaultKernelName": "csharp",
    "items": [
     {
      "aliases": [],
      "name": "csharp"
     }
    ]
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
